#include <string>
#include <fstream>
#include <iostream>
#include <vector>
#include <map>
#include <cstring>

const std::map<std::string, std::size_t> digitLetters {
    {"one", 1},
    {"two", 2},
    {"three", 3},
    {"four", 4},
    {"five", 5},
    {"six", 6},
    {"seven", 7},
    {"eight", 8},
    {"nine", 9},
};

void getFirstAndLast1(const std::string& line, std::size_t& first, std::size_t& last)
{
    bool firstTime{true};
    for (std::size_t i = 0; i < line.size(); ++i)
    {
        // Digit ?
        const char& ch{ line[i] }; 
        if (ch >= '0' && ch <= '9')
        {
            if (firstTime)
            {
                firstTime = false;
                first = ch - '0';
                last = ch - '0';
            }
            else
            {
                last = ch - '0';
            }
            continue;
        }

        // Letters
        for (const auto& kv : digitLetters)
        {
            if (i + kv.first.size() > line.size())
                continue;
            if (std::strncmp(&ch, kv.first.c_str(), kv.first.size()) == 0)
            {
                if (firstTime)
                {
                    firstTime = false;
                    first = kv.second;
                    last = kv.second;
                }
                else
                {
                    last = kv.second;
                }
            }
        }
    }   
}

void getFirstAndLast2(std::string line, std::size_t& first, std::size_t& last)
{
    std::size_t begin{0};
    std::size_t current{0};

    while (true)
    {
        begin = current;
        switch (line[current++])
        {
        case 'e':
        {
            if (line.size() > begin + 4 && line.substr(begin + 1, 4) == "ight")
                line.replace(begin, 5, "8");
            break;
        }
        case 'f':
        {
            if (line.size() > begin + 3 && line.substr(begin + 1, 3) == "ive")
                line.replace(begin, 4, "5");
            else if (line.size() > begin + 3 && line.substr(begin + 1, 3) == "our")
                line.replace(begin, 4, "4");
            break;
        }
        case 'n':
        {
            if (line.size() > begin + 3 && line.substr(begin + 1, 3) == "ine")
                line.replace(begin, 4, "9");
            break;
        }
        case 'o':
        {
            if (line.size() > begin + 2 && line.substr(begin + 1, 2) == "ne")
                line.replace(begin, 3, "1"); 
            break;
        }
        case 's':
        {
            if (line.size() > begin + 2 && line.substr(begin + 1, 2) == "ix")
                line.replace(begin, 3, "6");
            else if (line.size() > begin + 4 && line.substr(begin + 1, 4) == "even")
                line.replace(begin, 5, "7");
            break;
        }
        case 't':
        {
            if (line.size() > begin + 2 && line.substr(begin + 1, 2) == "wo")
                line.replace(begin, 3, "2");
            else if (line.size() > begin + 4 && line.substr(begin + 1, 4) == "hree")
                line.replace(begin, 5, "3");
            break;
        }
        case 'z':
        {
            if (line.size() > begin + 3 && line.substr(begin + 1, 3) == "ero")
                line.replace(begin, 4, "0");
            break;
        }
        default:
            break;
        }
        if (line.size() <= current)
            break;
    }

    std::size_t firstIndex{ line.find_first_of("123456789") };
    std::size_t lastIndex{ line.find_last_of("123456789") };

    first = line[firstIndex] - '0';
    last = line[lastIndex] - '0';
}

int main() 
{

    std::ifstream file{ "./src/day01/input.txt" };
    std::ofstream out1{"./src/day01/output1.txt"};
    std::ofstream out2{"./src/day01/output2.txt"};

    std::string line{};
    std::size_t sum1{0};
    std::size_t sum2{0};

    while ( std::getline(file, line) ) 
    {
        std::size_t last1{0};
        std::size_t first1{0};

        std::size_t last2{0};
        std::size_t first2{0};

        getFirstAndLast1(line, first1, last1);
        getFirstAndLast2(line, first2, last2);

        std::size_t result1 = 10 * first1 + last1;
        std::size_t result2 = 10 * first2 + last2;

        out1 << line << " ==> " << result1 << std::endl;
        out2 << line << " ==> " << result2 << std::endl;
        
        sum1 += result1;
        sum2 += result2;

        if (result1 != result2)
            std::cout << "Diff in " << line << std::endl;
    }

    std::cout << sum1 << std::endl;
    std::cout << sum2 << std::endl;

    return 0;
}